<?php

namespace App\Game\Logic;

use App\Game\Conf\GameProgress;
use App\Game\Conf\MainCmd;
use App\Game\Conf\SubCmd;
use App\Game\Core\AStrategy;
use App\Game\Core\Packet;
use App\Game\Timer\GameTimer;
use App\Service\Lock;
use App\Task\GameTimerTask;
use App\Task\PlayCardTask;

/**
 *  打牌响应
 */
class OutCard extends AStrategy
{
    /**
     * 执行方法
     */
    public function exec()
    {
        $game_conf = config('game');
        $account = $this->_params['userinfo']['account'];
        //防止重复操作
        if (!Lock::lock($account . '_out_card', 2)) {
            return;
        }
        $fd = $this->_params['userinfo']['fd'];
        $inutData = $this->_params['data']; // ['card'=>2]
        $user_room_map_key = sprintf($game_conf['user_room'], $account);
        $room_no = redis()->get($user_room_map_key);
        $user_room_data = getRoomData($room_no);
        $serv = server();
        $out_cards = $inutData['card'];
        if (!$out_cards) {
            $msg = array('status' => 1, 'info' => '出牌数据不能为空！');
            pushErr($serv, $fd, SubCmd::SUB_GAME_OUT_CARD_RESP, $msg);
            return;
        }
        if (!checkGameProgress($room_no, GameProgress::GAME_OUT_CARD)) {
            $msg = array('status' => 1, 'info' => '出牌非法, 还未到出牌阶段！');
            pushErr($serv, $fd, SubCmd::SUB_GAME_OUT_CARD_RESP, $msg);
            return;
        }
        //检查操作是否已经超时
        if (!checkCounter($room_no)) {
            $msg = ['status' => 1, 'info' => '该操作已超时，系统已自动为您执行默认操作'];
            pushErr($serv, $fd, SubCmd::SUB_GAME_OUT_CARD_RESP, $msg);
            return;
        }
        //检查出的牌是否在用户手牌中
        $user_data = json_decode($user_room_data[$account], true);
        if (!in_array($out_cards, $user_data['card'])) {
            $msg = ['status' => 1, 'info' => '出牌非法，出牌数据不存在'];
            pushErr($serv, $fd, SubCmd::SUB_GAME_OUT_CARD_RESP, $msg);
            return;
        }
        //手次
        $hand_num = isset($user_room_data['hand_num']) ? $user_room_data['hand_num'] + 1 : 1;
        $master = json_decode($user_room_data['master'], true);
        //首次出牌，判断是否为庄家出牌
        $chair_id = findChairId($room_no, $account); // 座位号
        if ($hand_num == 1) {
//            dd('out_cards[chair_id]', $out_cards['chair_id']);
//            dd('master', $master);
            if ($chair_id != $master) {
                $msg = array('status' => 1, 'info' => '出牌非法, 当前为庄家出牌');
                pushErr($serv, $fd, SubCmd::SUB_GAME_OUT_CARD_RESP, $msg);
                return;
            }
        }
        if (isset($user_room_data['next_chair_id']) && $user_room_data['next_chair_id'] != $chair_id) {
            $msg = array('status' => 2, 'info' => '出牌非法, 还未轮到您出牌');
            pushErr($serv, $fd, SubCmd::SUB_GAME_OUT_CARD_RESP, $msg);
            return;
        }
        //判断总手牌数，是否存在重复出牌，杠牌也按3张牌算，这样可以保证总牌数不变是13，判断总牌数就更简单
        $totalCardNum = count($user_data['card']) + count($user_data['peng']) * 3 + count($user_data['gang']) * 3;
        if ($totalCardNum < 14) {
            $msg = array('status' => 3, 'info' => '出牌非法，重复出牌');
            pushErr($serv, $fd, SubCmd::SUB_GAME_OUT_CARD_RESP, $msg);
            return;
        }
        //验证出牌数据
        if (!in_array($out_cards, config('mj'))) {
            $msg = array('status' => 3, 'info' => '出牌非法, 请出手牌');
            pushErr($serv, $fd, SubCmd::SUB_GAME_OUT_CARD_RESP, $msg);
            return;
        }
        //设置出牌缓存
        updateRoomData($room_no, ['out' => ['card' => $out_cards, 'chair_id' => $chair_id]]);
        ddTitle('do_out_card 0000000000 ');
        //清除前一个定时器
        putTimerDel($room_no);
        GameTimer::do_out_card($room_no, ['card' => $out_cards, 'chair_id' => $chair_id]);
    }

}